local NetMessage = {}
NetMessage.__index = NetMessage

Tubes.Networking.NetMessage = Tubes.MakeConstructor (NetMessage)

function NetMessage:ctor (name, recipients)
	self.Name = name
	self.Recipients = recipients
	
	self.Data = {}
	self.Types = {}
	self.Length = 0
end

function NetMessage:BitField (...)
	local Bits = {...}
	local Value = 0
	local Weight = 1
	for i = 1, 8 do
		if Bits [i] then
			Value = Value + Weight
		end
		Weight = Weight * 2
	end
	self:UChar (Value)
end

function NetMessage:Char (value)
	self.Data [#self.Data + 1] = value
	self.Types [#self.Types + 1] = "Char"
	self.Length = self.Length + 1
end

function NetMessage:End ()
	if self.Length < 255 then
		umsg.Start ("T" .. self.Name, self.Recipients)
		for i = 1, #self.Types do
			local Type = self.Types [i]
			local Value = self.Data [i]
			umsg [Type] (Value)
		end
		umsg.End ()
	else
		-- Ew.
		datastream.StreamToClients (self.Recipients or player.GetAll (), "TDS", {self.Name, self.Data})
	end
end

function NetMessage:Float (value)
	self.Data [#self.Data + 1] = value
	self.Types [#self.Types + 1] = "Float"
	self.Length = self.Length + 4
end

function NetMessage:Long (value)
	self.Data [#self.Data + 1] = value
	self.Types [#self.Types + 1] = "Long"
	self.Length = self.Length + 4
end

function NetMessage:Player (value)
	if type (value) ~= "Player" then
		self:UChar (255)
		return
	end
	self:UChar (value:EntIndex ())
end

function NetMessage:Short (value)
	self.Data [#self.Data + 1] = value
	self.Types [#self.Types + 1] = "Short"
	self.Length = self.Length + 2
end

function NetMessage:String (value)
	self.Data [#self.Data + 1] = value
	self.Types [#self.Types + 1] = "String"
	self.Length = self.Length + value:len () + 1
end

function NetMessage:UChar (value)
	self:Char (value - 128)
end

function NetMessage:ULong (value)
	self:Long (value - 2147483648)
end

function NetMessage:UShort (value)
	self:Short (value - 32768)
end